package com.sz.app.oss.system;

import com.sz.app.oss.system.RoleAggregationService;
import com.sz.common.base.dao.Pagination;
import com.sz.common.base.dao.ParamData;
import com.sz.common.base.dto.QResultDto;
import com.sz.common.base.dto.ResultDto;
import com.sz.common.base.service.AbstractService;
import com.sz.common.base.utils.EntityUtils;
import com.sz.common.base.utils.StringUtils;
import com.sz.common.core.service.PrincipalUtils;
import com.sz.common.core.system.entity.Role;
import com.sz.common.core.system.entity.Org;
import com.sz.common.core.system.entity.UserOrg;
import com.sz.common.core.system.service.OrgService;
import com.sz.common.core.system.service.UserService;
import com.sz.app.oss.api.system.dto.UserAndOrgDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * Function: RoleAggregationServiceImpl <br>
 * Author: Penghui.zheng，Charles <br>
 * Date: 2017-01-19 20:06:00
 */
@Service("roleAggregationService")
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class RoleAggregationServiceImpl extends AbstractService implements RoleAggregationService {

    @Autowired
    private OrgService orgsService;
    @Autowired
    private UserService userService;

    @Override
    protected String getMapperNamespace() {
        return "RoleAggregationMapper";
    }

    /**
     * 根据角色成员类型查找角色成员
     *
     * @param pd
     * @param roleType 成员类型
     * @return
     */
    private List<UserAndOrgDto> getUserAndOrgByRoleId(ParamData pd, String roleType) {
        List<UserAndOrgDto> list = new ArrayList<UserAndOrgDto>();
        if (!StringUtils.isEmpty(roleType)) {
            if ("0".equals(roleType)) {
                list = dao.findForList(this.getSqlName("serchRoleListPage"), pd, UserAndOrgDto.class);
                return list;
            } else if ("1".equals(roleType)) {
                list = dao.findForList(this.getSqlName("serchRoleByUserListPage"), pd, UserAndOrgDto.class);
                return list;
            } else if ("2".equals(roleType)) {
                list = dao.findForList(this.getSqlName("serchRoleByOrgListPage"), pd, UserAndOrgDto.class);
                return list;
            } else {
                list = dao.findForList(this.getSqlName("serchRoleByGroupListPage"), pd, UserAndOrgDto.class);
                return list;
            }
        }
        return list;
    }

    /**
     * 搜索角色下的用户和组织
     *
     * @see RoleAggregationService#searchRoleListPage
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public ResultDto searchRoleListPage(Integer roleId, String q, String roleType, int pageIndex, int pageSize) {
        QResultDto dto = new QResultDto();
        int domainId = PrincipalUtils.getDomainId();
        ParamData pd = new ParamData();
        q = StringUtils.replaceSqlPattern(q);
        pd.put("q", q);
        pd.put("domainId", domainId);
        pd.put("id", roleId);
        Pagination page = new Pagination();
        page.setCurrentPage(pageIndex);
        page.setPageSize(pageSize);
        pd.setPagination(page);
        // 查询角色下的用户和组织机构的
        List<UserAndOrgDto> list = getUserAndOrgByRoleId(pd, roleType);
        for (UserAndOrgDto userAndOrgDto : list) {
            String type = userAndOrgDto.getType();
            if ("0".equals(type)) { // 用户
                int userId = userAndOrgDto.getId();
                ParamData userPd = new ParamData();
                userPd.put("userId", userId);
                userPd.put("domainId", domainId);
                // 所有角色总和
                List<Role> listAll = new ArrayList<Role>();
                // 查找用户自己所拥有的角色
                List<Role> urs = dao.findForList(this.getSqlName("findByUserId"), userPd, Role.class);
                // 查找用户的组织机构
                List<UserOrg> userOrgList = userService.getOrgByUserId(userId);
                // 组织机构所拥有的角色
                List<Role> orgRole1List = new ArrayList<Role>();
                // 用户组所拥有的角色
                List<Role> orgRole2List = new ArrayList<Role>();
                for (UserOrg userOrg : userOrgList) {
                    int orgId = userOrg.getOrgId();
                    String[] codeArry = orgsService.getOrgParentByOrgId(orgId);
                    Org org= orgsService.findById(userOrg.getOrgId());
                    if(org.getOrgGroupId().equals(2)){
                        // 用OrgCode查找用户组所拥有的角色
                    	 orgRole2List = getRoleByOrgCodeUser(codeArry, 2);
                    	 for (Role r : orgRole2List) {                   	
                   		     r.setType("2");
                             listAll.add(r);  
                         }
                    }
                    else{
                    	 // 用OrgCode查找组织机构所拥有的角色
                        orgRole1List = getRoleByOrgCodeUser(codeArry, 1);
                        for (Role r : orgRole1List) {                   	
                   		    r.setType("1");
                            listAll.add(r);                      
                        }
                    }                                                       
                }
                for (Role r : urs) {
                    r.setType("0");
                    listAll.add(r);
                }
                userAndOrgDto.setList(listAll);
            } else { // 组织机构和用户组
                int orgId = userAndOrgDto.getId();
                ParamData owenOrgPd = new ParamData();
                owenOrgPd.put("orgId", orgId);
                owenOrgPd.put("domainId", domainId);
                // 所有角色总和
                List<Role> listAll = new ArrayList<>();
                List<Role> owen = dao.findForList(this.getSqlName("findByOrgId"), owenOrgPd, Role.class);
                List<Role> owenReset = new ArrayList<>();
                for (Role role : owen) {
                    Role roleReset = new Role();
                    EntityUtils.copyPropertiesIgnoreNull(role, roleReset);
                    owenReset.add(roleReset);
                }
                ParamData orgPd = new ParamData();
                orgPd.put("orgId", orgId);
                // 根据部门id查找部门
                String[] codeArry = orgsService.getOrgParentByOrgId(orgId);
                if ("1".equals(type)) {
                    // 用OrgCode查找组织机构所拥有的角色
                    List<Role> orgRole1List = getRoleByOrgCode(codeArry, 1);
                    for (Role r : orgRole1List) {
                    		  r.setType("1");
                              listAll.add(r);  
                    }
                    for (Role r : owenReset) {
                        r.setType("0");
                        listAll.add(r);
                    }
                } else {
                    // 用OrgCode查找用户组所拥有的角色
                    List<Role> orgRole2List = getRoleByOrgCode(codeArry, 2);
                    for (Role r : orgRole2List) {  	
                    	    r.setType("2");
                            listAll.add(r); 
                    }
                    for (Role r : owenReset) {
                        r.setType("0");
                        listAll.add(r);
                    }
                }
                userAndOrgDto.setList(listAll);
            }
        }
        dto.setData(list);
        dto.setPagination(page);
        return dto;
    }

    /**
     * 查询部门和组织的所有角色
     *
     * @param codeArry 部门集合
     * @param type     类型：1组织，2用户组
     * @return
     */
    private List<Role> getRoleByOrgCode(String[] codeArry, int type) {
        List<Role> list = new ArrayList<Role>();
        if (codeArry != null && codeArry.length > 0) {
            for (int i = 0; i < codeArry.length - 1; i++) {
                // 部门code
                String orgCode = codeArry[i];
                ParamData orgRolePd = new ParamData();
                orgRolePd.put("orgGroupId", type);
                orgRolePd.put("code", orgCode);
                // 根据部门code和orgGroupId查找部门
                Org org = (Org) dao.findForObject("OrgMapper.findOrgByCode", orgRolePd);
                if (org != null) {
                    int orgId = org.getId();
                    int domainId = PrincipalUtils.getDomainId();
                    ParamData oRolePd = new ParamData();
                    oRolePd.put("orgId", orgId);
                    oRolePd.put("domainId", domainId);
                    // 查找部门的角色吧
                    List<Role> roleList = dao.findForList(this.getSqlName("findByOrgId"), oRolePd, Role.class);
                    if (roleList != null && roleList.size() > 0) {
                        for (Role role : roleList) {
                            int flag = 0;
                            for (Role r : list) {
                                if (r.getId().equals(role.getId())) {
                                    flag = 1;
                                }
                            }
                            if (flag == 0) {
                                list.add(role);
                            }
                        }
                    }
                }
            }
        }
        return list;
    }

    /**
     * 查询部门和组织的所有角色
     *
     * @param codeArry 部门集合
     * @param type     类型：1组织，2用户组
     * @return
     */
    private List<Role> getRoleByOrgCodeUser(String[] codeArry, int type) {
        List<Role> list = new ArrayList<Role>();
        if (codeArry != null && codeArry.length > 0) {
            for (int i = 0; i < codeArry.length; i++) {
                // 部门code
                String orgCode = codeArry[i];
                ParamData orgRolePd = new ParamData();
                orgRolePd.put("orgGroupId", type);
                orgRolePd.put("code", orgCode);
                // 根据部门code和orgGroupId查找部门
                Org org = (Org) dao.findForObject("OrgMapper.findOrgByCode", orgRolePd);
                if (org != null) {
                    int orgId = org.getId();
                    int domainId = PrincipalUtils.getDomainId();
                    ParamData oRolePd = new ParamData();
                    oRolePd.put("orgId", orgId);
                    oRolePd.put("domainId", domainId);
                    // 查找部门的角色吧
                    List<Role> roleList = dao.findForList(this.getSqlName("findByOrgId"), oRolePd, Role.class);
                    if (roleList != null && roleList.size() > 0) {
                        for (Role role : roleList) {
                            int flag = 0;
                            for (Role r : list) {
                                if (r.getId().equals(role.getId())) {
                                    flag = 1;
                                }
                            }
                            if (flag == 0) {
                                list.add(role);
                            }
                        }
                    }
                }
            }
        }
        return list;
    }
}
